﻿using System;
using System.Collections.Generic;
using System.Net.Mime;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Drawing;
using Biz;
using Common;
using IBiz;
using PlateDSP;

namespace MainSystemForm
{
    public class MyDsp : CPlateDSP
    {
        /// <summary>
        /// 被识别的车牌号码
        /// </summary>
        public string PlateNum;

        #region 控件注入

        //提示信息框
        public RichTextBox richTextBox;

        //入口识别车牌显示框
        public TextBox txtInPlateNum;

        //出口识别车牌显示框
        public TextBox txtOutPlateNum;

        //截图图像
        public PictureBox pictureBoxPic;

        //左边 进入日期label
        public Label lblInDate1;

        //进入有效时间label
        public Label lblInEffectiveTime;

        //右边 进入日期label
        public Label lblInDate2;

        //出去日期label
        public Label lblOutDate;

        //出去有效时间label
        public Label lblOutEffectiveTime;

        #endregion

        private DateTime dtNow;
        private string filePathName;
        private Dictionary<int, string> dicLightRealyIndex = new Dictionary<int, string>();
        private Dictionary<int, string> dicCoilRealyIndex = new Dictionary<int, string>();
        private Dictionary<int, string> dicPicturePath = new Dictionary<int, string>();
        private bool execBiz = false;

        /// <summary>
        /// 线圈 停止信号量
        /// </summary>
        private volatile bool coilThreadStop;

        public MyDsp()
        {
            dicLightRealyIndex.Add(SystemConstant.DeviceInNo, SystemConfig.InLightSwitch);
            dicLightRealyIndex.Add(SystemConstant.DeviceOutNo, SystemConfig.OutLightSwitch);

            dicCoilRealyIndex.Add(SystemConstant.DeviceInNo, SystemConfig.InInductionCoilStatus);
            dicCoilRealyIndex.Add(SystemConstant.DeviceOutNo, SystemConfig.OutInductionCoilStatus);

            dicPicturePath.Add(SystemConstant.DeviceInNo, SystemConfig.InPicturePath);
            dicPicturePath.Add(SystemConstant.DeviceOutNo, SystemConfig.OutPicturePath);
        }
        
        private void SaveRecord(UInt32 Target, uint CarImageBufferBlockId, int deviceIndex)
        {
            if (StatGetTargetSavedFlags(Target))
            {
                return;
            }
            StatSetTargetSavedFlags(Target, true);
            if (StatSetCurrentTarget(DSP_STAT_FILTER, (int) Target) != 0)
            {
                StringBuilder Number = new StringBuilder(64);
                if (0 != GetPlateNumber(Number, 64))
                {
                    PlateNum = Number.ToString();
                }
                
                dtNow = DateTime.Now;

                filePathName = dicPicturePath[deviceIndex] + "\\" + dtNow.ToString("yyyyMMddHHmmss") + ".jpg";
                BufferSave(CarImageBufferBlockId, 0, filePathName, 0);

                Thread.Sleep(500);
            }
        }

        public override void AfterFilterStateChanged(int Event, UInt32 Target)
        {
            uint CarImageBufferBlockId = Target;
            StatSetCurrentTarget(DSP_STAT_NONE, (int) Target);

            //取得摄像头设备序号（是进入模式还是驶出模式）
            var deviceIndex = this.VideoGetDeviceIndex();

            switch (Event)
            {
                case DSP_FILTER_OUT_VIEW:
                case DSP_FILTER_BEFORE_CLEAR:
                    //逻辑执行标志--结束
                    execBiz = false;

                    //后半部分逻辑处理
                    BizEnd(Target, deviceIndex);

                    break;
                case DSP_FILTER_NEW_PLATE:
                    StatSetTargetSavedFlags(Target, false);
                    BufferImageStream(CarImageBufferBlockId);
                    break;
                case DSP_FILTER_LIKE_PLATE:
                case DSP_FILTER_SAME_PLATE:
                    if (StatSetCurrentTarget(DSP_STAT_FILTER, (int) Target) != 0)
                    {
                        if (ImageIsBest() != 0 && !execBiz)
                        {
                            BufferImageStream(CarImageBufferBlockId);
                            SaveRecord(Target, CarImageBufferBlockId, deviceIndex);
                            //前半部分逻辑处理
                            BizStart(Target, deviceIndex);
                        }                        
                    }

                    break;
            }
        }

        private void BizEnd(uint target, int deviceIndex)
        {
            //道闸Biz
            var barrier = new Barrier(SystemConfig.GateSwitch);

            //同向信号灯Biz
            var sameLight = new Light(dicLightRealyIndex[deviceIndex]);

            //关闭道闸
            if (barrier.GetValue() == EcmdI2CResponse.Open
                || barrier.GetValue() == EcmdPinResponse.On)
            {
                barrier.Close();
            }

            //关闭信号灯
            if (sameLight.GetValue() == EcmdI2CResponse.Open
                || sameLight.GetValue() == EcmdPinResponse.On)
            {
                sameLight.Close();
            }

            // 监控线圈线程 终止
            this.coilThreadStop = true;

            //todo 数据保存
        }

        private void BizStart(UInt32 Target, int deviceIndex)
        {
            //逻辑执行标志
            execBiz = true;

            //截图图像显示
            this.pictureBoxPic.Image = Image.FromFile(filePathName);


            //警报器Biz
            var alarm = new Alarm(SystemConfig.WarnSwitch);

            //道闸Biz
            var barrier = new Barrier(SystemConfig.GateSwitch);

            //同向信号灯Biz
            var sameLight = new Light(dicLightRealyIndex[deviceIndex]);
            //反向信号灯Biz
            var reverseLight = new Light(dicLightRealyIndex[(deviceIndex + 1)%2]);

            //同向线圈Biz
            var sameCoil = new Coil(dicCoilRealyIndex[deviceIndex]);
            //反向线圈Biz
            var reverseCoil = new Coil(dicCoilRealyIndex[(deviceIndex + 1) % 2]);

            //视频识别处理
            if (StatSetCurrentTarget(DSP_STAT_FILTER, (int) Target) != 0)
            {
                StringBuilder Number = new StringBuilder(64);
                if (0 != GetPlateNumber(Number, 64))
                {
                    PlateNum = Number.ToString();
                }
            }

            if (string.IsNullOrEmpty(PlateNum))
            {
                //车牌是空，无法识别
                richTextBox.Invoke(new Action(() =>
                {
                    richTextBox.Clear();
                    richTextBox.Text = SystemConstant.MsgPlateNotRecog;
                }));

                //警报开启                
                alarm.Open();

                return;
            }
            
            if (PlateNum.Contains("."))
            {
                //车牌不为空，部分识别
                richTextBox.Invoke(new Action(() =>
                {
                    richTextBox.Clear();
                    richTextBox.Text = SystemConstant.MsgPlatePartRecog;
                }));

                //警报开启                
                alarm.Open();

                //警报关闭                
                alarm.Close();

                return;
            }

            var plateBiz = new PlateBiz();

            if (!plateBiz.IsExistPlateNum(PlateNum))
            {
                //车牌没有登记，显示为“外来车辆”
                richTextBox.Invoke(new Action(() =>
                {
                    richTextBox.Clear();
                    richTextBox.Text = SystemConstant.MsgForeignVehicles;
                }));

                return;
            }

            if (plateBiz.IsInBlackList(PlateNum))
            {
                //黑名单车辆
                richTextBox.Invoke(new Action(() =>
                {
                    richTextBox.Clear();
                    richTextBox.Text = SystemConstant.MsgBalcklistVehicles;
                }));

                //警报开启                
                alarm.Open();

                //语音提示
                var voiceBroadcast = new VoiceBroadcast();
                voiceBroadcast.playBlackCarVoice();

                //警报关闭                
                alarm.Close();

                return;
            }

            //当前方向的反向信号灯变红
            reverseLight.Open();

            if (deviceIndex == SystemConstant.DeviceInNo)
            {
                this.txtInPlateNum.Text = PlateNum;
                this.lblInDate1.Text = dtNow.ToString("yy年MM月dd日");

                //todo
                this.lblInEffectiveTime.Text = "todo";
            }
            else
            {
                this.txtOutPlateNum.Text = PlateNum;
                this.lblInDate2.Text = "todo";
                this.lblOutDate.Text = dtNow.ToString("yy年MM月dd日");
                //todo
                this.lblOutEffectiveTime.Text = "todo";
            }

            //线圈识别 循环启动
            while (true)
            {
                var coilStatus = sameCoil.GetValue();

                if (EcmdPinResponse.On == coilStatus || EcmdI2CResponse.Open == coilStatus)
                {
                    break;
                }

                Thread.Sleep(100);

                //系统消息循环。用户如果要在主线程中循环等待时，可以调节器用该函数，
                //以保证消息的循环，以免引起系统阻塞。
                this.DoEvent();
            }

            //道闸开启
            barrier.Open();

            var thread = new Thread(() => ThreadBarrierStart(sameCoil,reverseCoil,alarm));
            this.coilThreadStop = false;
            thread.Start();
        }

        private void ThreadBarrierStart(Ecmd sameCoil, Ecmd reverseCoil,Ecmd alarm)
        {
            while (!this.coilThreadStop)
            {
                var sameCoilValue = sameCoil.GetValue();
                var reverseCoilValue = reverseCoil.GetValue();

                if ((reverseCoilValue == EcmdI2CResponse.Open
                     || reverseCoilValue == EcmdPinResponse.On)
                     && sameCoilValue == reverseCoilValue)
                {
                    //有尾随车辆
                    richTextBox.Invoke(new Action(() =>
                    {
                        richTextBox.Clear();
                        richTextBox.Text = SystemConstant.MsgTailVehicles;
                    }));

                    //警报开启                
                    alarm.Open();

                    //语音提示
                    var voiceBroadcast = new VoiceBroadcast();
                    voiceBroadcast.playFollowCarVoice();

                    //警报关闭                
                    alarm.Close();

                    this.coilThreadStop = true;
                }
            }
        }

    }
}
